package com.maimao.user.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.maimao.core.constant.Constants;
import com.maimao.core.enums.ExceptionEnum;
import com.maimao.core.exception.MaiMaoDaoException;
import com.maimao.core.exception.MaiMaoException;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.DateUtils;
import com.maimao.email.EmailSender;
import com.maimao.model.goods.Brand;
import com.maimao.model.user.Enterprise;
import com.maimao.model.user.Shop;
import com.maimao.model.user.enums.RoleEnum;
import com.maimao.model.user.enums.ShopStatus;
import com.maimao.model.user.sys.Resources;
import com.maimao.model.user.sys.Role;
import com.maimao.model.user.sys.vo.Permissions;
import com.maimao.user.client.BrandClient;
import com.maimao.user.mapper.CompanyMapper;
import com.maimao.user.mapper.ShopMapper;
import com.maimao.user.mapper.sys.ResourcesMapper;
import com.maimao.user.mapper.sys.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author MaoLin Wang
 * @date 2020/12/13 10:02 下午
 */
@Service
@Slf4j
public class CompanyService {
    private static final String COMPANY_CHECK_RESULT_CONTENT = "尊敬的{}先生/女士，您在麦猫商场的入驻审核结果为：<span style='font-size:20px;color:red'>{}<br/>";
    private static final String COMPANY_CHECK_FAIL_CONTENT = "审核未通过原因如下：<br/><span style='font-size:17px;font-weight:600'>企业资质：<span>{}<br/>" +
            "<span style='font-size:17px;font-weight:600'>品牌绑定：<span>{}";
    @Autowired
    private CompanyMapper companyMapper;


    @Autowired
    private ResourcesMapper resourcesMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private BrandClient brandClient;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Resource(name = "userEmailSendPool")
    private ThreadPoolTaskExecutor userEmailSendPool;

    @Autowired
    private EmailSender emailSender;

    public static final String COMPANY_CHECK_SUBJECT = "麦猫入驻审核结果";

    /**
     * 根据邮箱查询角色权限信息
     */
    public Permissions getPermissionsByEmail(String email) {
        Enterprise enterprise = companyMapper.selectByEmail(email);
        if (enterprise == null) {
            return null;
        }
        Permissions permissions = getPermissions(enterprise);
        return permissions;
    }

    private Permissions getPermissions(Enterprise enterprise) {
        Permissions permissions = new Permissions();
        permissions.setId(enterprise.getId());
        permissions.setAvatar(Constants.EMPTY);
        permissions.setUsername(enterprise.getEmail());
        permissions.setPassword(enterprise.getPassword());
        permissions.setMobile(Constants.EMPTY);
        Shop shop = shopMapper.findShopByOwnerAndSocial(enterprise.getId(), 1);
        permissions.setShopId(shop == null ? null : shop.getId());
        List<Role> roles = enterprise.getRoleList();
        if (roles != null && roles.size() > 0) {
            List<String> roleNames = roles.stream().map(Role::getRoleCode).collect(Collectors.toList());
            List<Integer> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());

            permissions.setRoles(roleNames);
            List<Resources> resourcesList = resourcesMapper.selectByRoleIdBatch(roleIds);
            if (resourcesList != null && resourcesList.size() > 0) {
                List<String> resourcesNames = resourcesList.stream().map(Resources::getCode).collect(Collectors.toList());
                permissions.setResources(resourcesNames);
            }
        }
        return permissions;
    }


    /**
     * 注册企业  并申请品牌和店铺
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void register(Enterprise enterprise) {
        enterprise.setShopStatus(ShopStatus.APPLYING.getCode());
        enterprise.setPassword(bCryptPasswordEncoder.encode(enterprise.getPassword()));
        companyMapper.insert(enterprise);
        sysUserMapper.addUserRoleRecord(enterprise.getId(), Lists.newArrayList(RoleEnum.ROLE_WEB_ENTERPRISE.getId()));


        Brand brand = enterprise.getBrand();

        Shop shop = Shop.builder()
                .social(1)
                .owner(enterprise.getId())
                .name(brand.getName() + "官方旗舰店")
                .createTime(DateUtils.now()).build();
        shopMapper.insert(shop);
        if (brand.getId() == null) {
            //申请新品牌
            Result<Long> addBrand = brandClient.addBrand(Brand.builder().name(brand.getName()).logo(brand.getLogo()).ownerId(enterprise.getId()).shopId(shop.getId()).build());
            if (addBrand == null || addBrand.getData() == null) {
                throw new MaiMaoException(ExceptionEnum.BRAND_EXIST_ERROR);
            }
            brand.setId(addBrand.getData());
        }
        //修改为品牌ID
        shopMapper.updateBrandId(shop.getId(), brand.getId());


    }

    public boolean checkEmail(String email) {
        Enterprise enterprise = companyMapper.selectByEmail(email);
        return enterprise == null;
    }

    public Integer findShopStatusById(Long id) {
        return companyMapper.findShopStatusById(id);
    }

    public List<Enterprise> queryShopCheck() {
        List<Enterprise> enterpriseList = companyMapper.queryShopCheck();
        if (ObjectUtil.isNotEmpty(enterpriseList)){
            for (Enterprise enterprise : enterpriseList) {
                Shop shop = shopMapper.findShopByOwnerAndSocial(enterprise.getId(), 1);
                enterprise.setShopId(shop.getId());
            }
        }
        return enterpriseList;

    }


    /**
     * 审核企业店铺
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public Result checkShop(Long companyId, Boolean success, String reason) {
        Shop shop = shopMapper.findShopByOwnerAndSocial(companyId, 1);
        if (shop==null){
            return Result.notValid("尚未创建店铺");
        }
        Result<Brand> brandResult = brandClient.queryBrandByShopId(shop.getId());
        if (brandResult != null && brandResult.getData() == null) {
            return Result.notValid("尚未绑定品牌");
        }
        Brand brand = brandResult.getData();
        if (!brand.getStatus().equals(1)) {
            return Result.notValid("请先审核绑定的品牌");
        }

        Enterprise enterprise = companyMapper.selectById(companyId);
        if (enterprise == null) {
            return Result.notValid("企业不存在");
        }
        boolean finalResult = success;
        if (success && brand.getStatus().equals(0)) {
            finalResult = false;
        }
        companyMapper.updateShopStatus(companyId, finalResult ? ShopStatus.OPEN.getCode() : ShopStatus.FAIL.getCode(), reason);

        String content = COMPANY_CHECK_RESULT_CONTENT;
        if (finalResult) {
            //品牌和企业都审核通过，添加店铺角色
            sysUserMapper.deleteRoleBatch(companyId,Lists.newArrayList(RoleEnum.ROLE_WEB_SHOP.getId()));
            sysUserMapper.addUserRoleRecord(companyId, Lists.newArrayList(RoleEnum.ROLE_WEB_SHOP.getId()));
            content = StrUtil.format(content, enterprise.getLegalPerson(), "审核通过");
        } else {
            content += COMPANY_CHECK_FAIL_CONTENT;
            content = StrUtil.format(content, enterprise.getLegalPerson(), "未通过", success ? "通过" : reason, brand.getStatus().equals(1) ? "通过" : brand.getFailReason());
        }

        String finalContent = content;
        userEmailSendPool.submit(() -> {
            log.info("准备发送企业审核结果邮件..........");

            log.info("企业审核——发送邮件，内容：{},to:{},code:{}", finalContent, enterprise.getEmail());
            emailSender.sendHtml(COMPANY_CHECK_SUBJECT, enterprise.getEmail(), finalContent);

        });
        return Result.ok("审核成功");
    }
}
